{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "8ca2e60d-17c0-40fc-91c6-c16915b39c06",
   "metadata": {},
   "outputs": [],
   "source": [
    "import re, html, json\n",
    "import requests\n",
    "from urllib.error import HTTPError\n",
    "from openai import OpenAI\n",
    "from IPython.display import Markdown, display, update_display\n",
    "from youtube_transcript_api import YouTubeTranscriptApi, NoTranscriptFound, TranscriptsDisabled, VideoUnavailable\n",
    "\n",
    "OLLAMA_API = \"http://localhost:11434/api/chat\"\n",
    "HEADERS = {\"Content-Type\": \"application/json\"}\n",
    "MODEL = \"llama3.2\"\n",
    "api_key='ollama'\n",
    "\n",
    "def yt_title_desc_transcript(url: str, lang=\"en\"):\n",
    "    \"\"\"\n",
    "    Returns {\"title\": str|None, \"description\": str|None, \"transcript\": str|None}.\n",
    "    - Title via oEmbed (no API key).\n",
    "    - Description scraped from the watch page (shortDescription).\n",
    "    - Transcript via youtube-transcript-api, gracefully handling 400/disabled.\n",
    "    \"\"\"\n",
    "    # --- extract 11-char video id ---\n",
    "    m = re.search(r\"(?:v=|/)([0-9A-Za-z_-]{11})|^([0-9A-Za-z_-]{11})$\", url)\n",
    "    vid = (m.group(1) or m.group(2)) if m else None\n",
    "    if not vid:\n",
    "        return {\"title\": None, \"description\": None, \"transcript\": None}\n",
    "\n",
    "    # --- title via oEmbed (very robust) ---\n",
    "    title = None\n",
    "    try:\n",
    "        r = requests.get(\"https://www.youtube.com/oembed\",\n",
    "                         params={\"url\": f\"https://www.youtube.com/watch?v={vid}\", \"format\": \"json\"},\n",
    "                         timeout=10)\n",
    "        if r.ok:\n",
    "            title = r.json().get(\"title\")\n",
    "    except Exception:\n",
    "        pass\n",
    "\n",
    "    # --- description from watch page (shortDescription in initial JSON) ---\n",
    "    description = None\n",
    "    try:\n",
    "        page = requests.get(f\"https://www.youtube.com/watch?v={vid}\", timeout=10).text\n",
    "        # Look for ytInitialPlayerResponse JSON\n",
    "        jmatch = re.search(r\"ytInitialPlayerResponse\\s*=\\s*({.*?});\", page, re.DOTALL)\n",
    "        if jmatch:\n",
    "            data = json.loads(jmatch.group(1))\n",
    "            desc = data.get(\"videoDetails\", {}).get(\"shortDescription\")\n",
    "            if desc:\n",
    "                description = html.unescape(desc)\n",
    "    except Exception:\n",
    "        pass\n",
    "\n",
    "    # --- transcript (handle 400 cleanly) ---\n",
    "    transcript_text = None\n",
    "    try:\n",
    "        items = YouTubeTranscriptApi.get_transcript(vid, languages=[lang])\n",
    "        transcript_text = \" \".join(ch[\"text\"].strip() for ch in items if ch.get(\"text\"))\n",
    "    except (NoTranscriptFound, TranscriptsDisabled, VideoUnavailable, HTTPError):\n",
    "        # HTTPError covers the \"HTTP Error 400: Bad Request\" case\n",
    "        transcript_text = None\n",
    "    except Exception:\n",
    "        transcript_text = None\n",
    "\n",
    "    return {\"title\": title, \"description\": description, \"transcript\": transcript_text}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ad9be496-4e91-4562-90f3-54d11208da55",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "system_prompt = '''\n",
    "You are an assistant that generates detailed yet concise summaries of YouTube videos.\n",
    "When the user provides a title and description of a YouTube video, your task is to write a coherent, engaging, and informative summary of around 500 words.\n",
    "The summary should:\n",
    "\n",
    "Capture the main themes and key points the video likely covers.\n",
    "\n",
    "Expand on the description logically, providing context and flow.\n",
    "\n",
    "Stay neutral, factual, and clear (no personal opinions).\n",
    "\n",
    "Be self-contained so it makes sense without needing to watch the video.\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "dd4be0bc-df1f-47e0-9e03-9b734117f80a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def user_prompt(title, description):\n",
    "    prompt = '''Provide me the YouTube video title and description.\\n\n",
    "    I will generate a clear, engaging, and concise summary of the video content in around 500 words,\\n\n",
    "    highlighting the main ideas, key points, and important details.\\n'''\n",
    "    prompt += f'here is the title : {title} \\n Description : {description} '\n",
    "    return prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "46896ad3-db1e-448a-8a03-036b9568c69f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def stream_youtube(yt_url):\n",
    "    ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\n",
    "    video_metadata = yt_title_desc_transcript(yt_url)\n",
    "    stream = ollama.chat.completions.create(\n",
    "        model=MODEL,\n",
    "        messages = [\n",
    "            {\"role\":\"system\", \"content\": system_prompt},\n",
    "            {\"role\":\"user\", \"content\": user_prompt(video_metadata['title'], video_metadata['description'])}\n",
    "        ],\n",
    "        stream=True\n",
    "        \n",
    "    )\n",
    "    response = \"\"\n",
    "    display_handle = display(Markdown(\"\"), display_id=True)\n",
    "    for chunk in stream:\n",
    "        response += chunk.choices[0].delta.content or ''\n",
    "        response = response.replace(\"```\",\"\").replace(\"markdown\", \"\")\n",
    "        update_display(Markdown(response), display_id=display_handle.display_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b59f8773-c13e-4050-ad3c-b578d07ef5e7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Here is a summary of the YouTube video:\n",
       "\n",
       "**Monta Re: A Baul-Inspired Tribute to the Mystic Guru Shankaracharya**\n",
       "\n",
       "The music video for \"Monta Re\" by Amit Trivedi, featuring Swanand Kirkire and Amitabh Bhattacharya, is a soulful tribute to the mystic guru Shankaracharya. Set in the Bengali folk music tradition, this song brings to life the ancient tales of Shankaracharya's spiritual journey.\n",
       "\n",
       "With elegant lyrics penned by Amitabh Bhattacharya, \"Monta Re\" transports listeners to the banks of the Ganges River, where Shankaracharya wandered in search of wisdom and inner peace. The song's haunting melodies and emotive vocals evoke a sense of longing and introspection, perfectly capturing the mystic guru's spiritual essence.\n",
       "\n",
       "The music video beautifully illustrates the baul-inspired style, with intricate traditional dance movements performed by a group of energetic dancers. The choreography seamlessly blends elements of Bengal's folk heritage with modern sensibilities, making the song an engaging watch for audience members interested in Indian classical music.\n",
       "\n",
       "**Music and Lyric Credit:**\n",
       "Amit Trivedi handles the music composition, ensuring that the melody complements the song's themes without overpowering them. Amitabh Bhattacharya takes credit for the lyrics, which tell stunning stories of Shankaracharya's spiritual adventures. The song features Swanand Kirkire and Amitabh Bhattacharya as vocalists, further enriching its emotional impact.\n",
       "\n",
       "**Relevance to Bengali Culture:**\n",
       "\"Monta Re\" is a heartwarming tribute to Bengal's rich cultural heritage. Inspired by the baul traditions of the region, this song honors Shankaracharya's life and spiritual journey without diminishing his significance in modern times. By showcasing these folk roots, \"Monta Re\" provides fans with an enriching sensory experience.\n",
       "\n",
       "You can listen to \"Monta Re\" along with other T-Series music videos released by Amit Trivedi at the links provided below:\n",
       "\n",
       "- Watch \"Ankahee\"\n",
       "- Check out \"Sawaar Loon\"\n",
       "- Explore \"Zinda Hoon\"\n",
       "\n",
       "Follow the official T-SERIES YouTube channel for an ever-growing variety of original music tracks!\n",
       "\n",
       "By embracing the richness of Bengali folk traditions, \"Monta Re\" embodies a musical reflection of Shankaracharya's extraordinary journey as both spiritual guide and symbol of timeless wisdom."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "stream_youtube('https://youtu.be/99NUJ1cLbBI?list=RDdJ6_aU6auZc')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "649287ca-aff8-4b59-91b7-731c007e83a7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
